#! /usr/bin/php
<?php
/*
 * 来电弹屏守护程序
 * 适用于Asterisk 1.6+
 * @since 1.0 2014-12-16 by sutroon<14507247@qq.com>
 * @remark 启动 php -f /var/lib/asterisk/bin/amisocket.php
 * @remark memcached -d -u root -m 64 -c 1024  (/etc/rc.d/rc.local, chkconfig memcached on)
 * @remark chkconfig /var/lib/asterisk/bin/amisocket.php
 */
set_time_limit(0);
// env check
if (!in_array('mysql', get_loaded_extensions())) {
    die('系统不支持mysql数据库扩展，请联系管理员开启!');
}
include '/var/lib/asterisk/agi-bin/phpagi-asmanager.php';

//$config = include '/var/www/html/ttf/App/Modules/XCall/Conf/config.php';
/**
 * 执行MySQL语句
 * @global array $config
 * @param string $sql
 * @since 1.0 <2015-4-8> SoChishun Added.
 */
function db_execute($sql) {
    global $config;
    if (!isset($config) || !$config) {
        echo '数据库配置无效' . PHP_EOL;
        exit;
    }
    $link = mysql_connect($config['DB_HOST'], $config['DB_USER'], $config['DB_PWD']);
    if (false === $link) {
        echo '数据库连接失败:' . mysql_error() . PHP_EOL;
        mysql_close($link);
        exit;
    }
    mysql_query('set names UTF8');
    mysql_select_db($config['DB_NAME']);
    $result = mysql_query($sql, $link);
    if (false === $result) {
        echo '执行失败:' . mysql_error() . PHP_EOL;
        mysql_close($link);
        exit;
    }
    mysql_close($link);
}

$astman = new AGI_AsteriskManager();
$try = false;
$trycount = 0;
while ($try || $trycount < 1) {
    if (!$astman->connect("127.0.0.1:5038", 'admin', 'amp111', 'on')) {
        $try = true;
        if ($trycount > 1) {
            echo "Try Connect Asterisk $trycount" . PHP_EOL;
        }
        sleep(5);
    } else {
        $try = false;
    }
    $trycount++;
}
$trycount = 0;
echo 'Connect CTI OK!' . PHP_EOL;

// 全局配置
// 开始呼叫时间
$astman->add_event_handler('Bridge', 'Bridge_handler'); // 建立通话事件
// $astman->add_event_handler('Newstate', 'Newstate_handler'); // 振铃事件(不用)
// $astman->add_event_handler('Unlink', 'Unlink_handler'); // 断开连接事件(不能被当成挂机事件，因为会在建立通话的时候执行到此事件)
// $astman->add_event_handler('Hangup', 'Hangup_handler'); // 挂机事件(为缓解数据库压力,暂时屏蔽 2015-1-13 by sutroon)
while (true) { //持续监听 程序相当一个守护进程持续监听 
    $astman->wait_response();
    if (date('s') < 1) {
        echo PHP_EOL . 'keeping mysql connection.';
        // mysql_query('select id from tcti_callrecord limit 1');
    }
}
$astsm->disconnect();
echo PHP_EOL . 'Disconnect OK!';

/**
 * 通话连接事件方法 for twcall
 * @param type $e
 * @param type $parameters
 * @param type $server
 * @param type $port
 * @since 2014-12-16 by sutroon
 * @remark 一次建立通话仅有一次,array ( 'Event' => 'Bridge', 'Privilege' => 'call,all', 'Bridgestate' => 'Link', 'Bridgetype' => 'core', 'Channel1' => 'Local/2000@from-internal-00000039;2', 'Channel2' => 'SIP/303-000000e1', 'Uniqueid1' => '1420081697.340', 'Uniqueid2' => '1420081697.341', 'CallerID1' => '81805', 'CallerID2' => '303', )
 */
function Bridge_handler($e, $parameters, $server, $port) {
    $filename = '/var/www/html/LSR/Conf/amisocket_conf.php';
    $ldtp_c2ie = 'Y'; // CallerID2_IS_Extension
    $ldtp_state = false;
    $ldtp_duplicate_expire = 1800;
    if (file_exists($filename)) {
        $config = include $filename;
        if (isset($config['ldtp_c2ie'])) {
            $ldtp_c2ie = $config['ldtp_c2ie'];
            $ldtp_state = $config['ldtp_state'];
        }
        if (isset($config['ldtp_duplicate_expire'])) {
            $ldtp_duplicate_expire = $config['ldtp_duplicate_expire'];
        }
    }
    if (!$ldtp_state) {
        return;
    }
    // array('CallerID2_IS_Extension'=>true);
    print_r($parameters);
    if ('Y' == $ldtp_c2ie) {
        $extension = $parameters['CallerID2']; // 302
        $lineNum = $parameters['CallerID1']; // 13950076987
    } else {
        $extension = $parameters['CallerID1']; // 302
        $lineNum = $parameters['CallerID2']; // 13950076987
    }
    if (!isset($lineNum) || !$lineNum || !$extension) {
        return;
    }
    //db_execute("update tuser_member set conn_count=conn_count+1 where userName='$extension'");
    //db_execute("insert into tcti_call_record (lineNum, extension) values ('$lineNum', '$extension')");
    $memcache = new Memcache;
    $memcache->connect('localhost', 11211);
    $duplicate = $memcache->get('temp-' . $extension); // 2015-5-13 SoChishun 判断是否重复记录
    //echo PHP_EOL,var_export('==read: $extension=' . $duplicate,true).PHP_EOL;
    if (!$duplicate || $lineNum != $duplicate) {
        //echo PHP_EOL,var_export("==set: $duplicate=$lineNum=$extension");
        $memcache->set($extension, $lineNum, MEMCACHE_COMPRESSED, 15); // 15秒没有获取则自动删除,被获取后立即删除
        $memcache->set('temp-' . $extension, $lineNum, MEMCACHE_COMPRESSED, $ldtp_duplicate_expire); // 2015-5-15 SoChishun 30分钟后自动过期,30分钟内不会重复弹,解决##转分机时重复呼上一个分机的问题
    }
    $memcache->close();
}

function Bridge_handler_xcall($e, $parameters, $server, $port) {
    //print_r($parameters);
    $channel1 = $parameters['Channel1']; // SIP/302-0000002e
    $channel2 = $parameters['Channel2']; // SIP/302-0000002e
    if (substr($channel1, 0, 3) == 'SIP') {
        if (substr($channel2, 0, 3) == 'SIP') { // 分机打分机
            /* 2015-5-12 台湾版注释
              $extension = $parameters['CallerID1']; // 302
              $lineNum = $parameters['CallerID2']; // 空值
             */
            $extension = $parameters['CallerID2']; // 302
            $lineNum = $parameters['CallerID1']; // 空值
            $uniqueid = $parameters['Uniqueid1'];
            $channel = $channel1;
        }
    } else {
        $channel = $channel2;
        $extension = $parameters['CallerID2']; // 302
        $lineNum = $parameters['CallerID1']; // 13950076987
        $uniqueid = $parameters['Uniqueid1']; // 不准
    }
    if (!isset($lineNum) || !$lineNum || !$extension) {
        return;
    }
    //db_execute("update tuser_member set conn_count=conn_count+1 where userName='$extension'");
    //db_execute("insert into tcti_call_record (lineNum, extension) values ('$lineNum', '$extension')");
    $memcache = new Memcache;
    $memcache->connect('localhost', 11211);
    $duplicate = $memcache->get($extension); // 判断是否重复记录
    if (!$duplicate || $lineNum != $duplicate) {
        $memcache->set($extension, $lineNum, MEMCACHE_COMPRESSED, 15); // 15秒没有获取则自动删除
    }
    $memcache->close();
}

/**
 * 通话挂机事件方法
 * == 建立通话后挂机 ==
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'Local/2000@from-internal-00000039;1<ZOMBIE>', 'Uniqueid' => '1420081697.341', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '<unknown>', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'Local/2000@from-internal-00000039;2', 'Uniqueid' => '1420081697.340', 'CallerIDNum' => '81805', 'CallerIDName' => '81805', 'ConnectedLineNum' => '303', 'ConnectedLineName' => '303', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'SIP/303-000000e1', 'Uniqueid' => '1420081697.339', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '81805', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',); // 这条才是有用的挂机事件
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'SIP/user1-000000e0', 'Uniqueid' => '1420081661.338', 'CallerIDNum' => '81805', 'CallerIDName' => '<unknown>', 'ConnectedLineNum' => '303', 'ConnectedLineName' => '303', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 * == 被叫摘机后直接挂机 ==
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'Local/2000@from-internal-0000003f;1', 'Uniqueid' => '1420083782.383', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '<unknown>', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'SIP/303-00000101', 'Uniqueid' => '1420083782.385', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '81805', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'Local/2000@from-internal-0000003f;2', 'Uniqueid' => '1420083782.384', 'CallerIDNum' => '81805', 'CallerIDName' => '81805', 'ConnectedLineNum' => '303', 'ConnectedLineName' => '303', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 * array('Event' => 'Hangup', 'Privilege' => 'call,all', 'Channel' => 'SIP/user1-00000100', 'Uniqueid' => '1420083775.382', 'CallerIDNum' => '81805', 'CallerIDName' => '<unknown>', 'ConnectedLineNum' => '303', 'ConnectedLineName' => '303', 'Cause' => '16', 'Cause-txt' => 'Normal Clearing',);
 */
function Hangup_handler($e, $parameters, $server, $port) {
    if (substr($parameters['Channel'], 0, 4) !== 'SIP/' || $parameters['CallerIDName'][0] == '<') {
        return;
    }
    $channel = $parameters['Channel']; // SIP/302-0000002e
    $extension = $parameters['CallerIDNum']; // 302
    $lineNum = $parameters['ConnectedLineNum']; // 13950076987
    $uniqueid = $parameters['Uniqueid'];
    print_r($parameters);
    $sql = "update tcti_callrecord set state=4 where cdrUniqueid='$uniqueid' or cdrChannel='$channel'";
    mysql_query($sql);
    if (mysql_errno() > 0) {
        echo $sql . PHP_EOL . mysql_error();
    }
}

/**
 * Newstate 一次通话有两次(振铃事件)
 * == 正常建立通话 ==
 * array ( 'Event' => 'Newstate', 'Privilege' => 'call,all', 'Channel' => 'SIP/303-000000e1', 'ChannelState' => '5', 'ChannelStateDesc' => 'Ringing', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '81805', 'Uniqueid' => '1420081697.341', );
 * array('Event' => 'Newstate', 'Privilege' => 'call,all', 'Channel' => 'SIP/303-000000e1', 'ChannelState' => '6', 'ChannelStateDesc' => 'Up', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '81805', 'Uniqueid' => '1420081697.341',); // 振铃时弹屏应该取此记录
 * == 被叫摘机后直接挂断 ==
 * array('Event' => 'Newstate', 'Privilege' => 'call,all', 'Channel' => 'SIP/303-00000101', 'ChannelState' => '5', 'ChannelStateDesc' => 'Ringing', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'ConnectedLineNum' => '81805', 'ConnectedLineName' => '81805', 'Uniqueid' => '1420083782.385',);
 */
function Newstate_handler($e, $parameters, $server, $port) {
    if ($parameters['ChannelStateDesc'] !== 'Up') {
        return;
    }
    $channel = $parameters['Channel']; // SIP/302-0000002e
    $extension = $parameters['CallerIDNum']; // 302
    $lineNum = $parameters['ConnectedLineNum']; // 13950076987
    $uniqueid = $parameters['Uniqueid'];
    // $sql = "insert into tcti_callrecord (cdrChannel, cdrUniqueid, extension, lineNum, state, siteID) select '$channel', '$uniqueid',extensionNumber,'$lineNum',0,siteID from db_xcall.tuser_member where extensionNumber=$extension and userType='SEAT' limit 1";
    // mysql_query($sql) or die(mysql_error());
    print_r($parameters);
}

/**
 * Unlink 一次通话出现2次 (不能被当成挂机事件，因为会在建立通话的时候执行到此事件)
 * == 建立通话后挂断 ==
 * array('Event' => 'Unlink', 'Privilege' => 'call,all', 'Channel1' => 'Local/2000@from-internal-00000039;2', 'Channel2' => 'Local/2000@from-internal-00000039;1<ZOMBIE>', 'Uniqueid1' => '1420081697.340', 'Uniqueid2' => '1420081697.341', 'CallerID1' => '81805', 'CallerID2' => '303',);
 * array('Event' => 'Unlink', 'Privilege' => 'call,all', 'Channel1' => 'SIP/user1-000000e0', 'Channel2' => 'SIP/303-000000e1', 'Uniqueid1' => '1420081661.338', 'Uniqueid2' => '1420081697.339', 'CallerID1' => '81805', 'CallerID2' => '303',);
 * == 被叫接听后直接挂断 ==
 * array (  'Event' => 'Unlink',  'Privilege' => 'call,all',  'Channel1' => 'SIP/user1-00000100',  'Channel2' => 'Local/2000@from-internal-0000003f;1',  'Uniqueid1' => '1420083775.382',  'Uniqueid2' => '1420083782.383',  'CallerID1' => '81805',  'CallerID2' => '303',);
 */
function Unlink_handler($e, $parameters, $server, $port) {
    if (substr($parameters['Channel1'], 0, 4) == 'SIP/') {
        echo $parameters['Channel1'] . PHP_EOL;
        return;
    }
    $channel = $parameters['Channel1']; // SIP/302-0000002e
    $extension = $parameters['CallerID2']; // 302
    $lineNum = $parameters['CallerID1']; // 13950076987
    $uniqueid = $parameters['Uniqueid2'];
    $sql = "update tcti_callrecord set state=4 where cdrUniqueid='$uniqueid'";
    mysql_query($sql) or die(mysql_error());
    print_r($parameters);
}

/**
 * Newexten 一次通话出现7次，里面数据没有什么价值
 * array('Event' => 'Newexten', 'Privilege' => 'dialplan,all', 'Channel' => 'Local/2000@from-internal-00000039;2', 'Context' => 'from-internal', 'Extension' => '2000', 'Priority' => '41', 'Application' => 'Set', 'AppData' => 'QUEUENUM=2000', 'Uniqueid' => '1420081697.340',);
 */

/**
 * Newchannel 一次通话出现2次,数据没有什么价值
 * array('Event' => 'Newchannel', 'Privilege' => 'call,all', 'Channel' => 'SIP/303-000000e1', 'ChannelState' => '0', 'ChannelStateDesc' => 'Down', 'CallerIDNum' => '303', 'CallerIDName' => '303', 'AccountCode' => false, 'Exten' => false, 'Context' => 'xcall', 'Uniqueid' => '1420081697.341',);
 */


